package gui.wizard;

import gui.MaiaWorld;
import java.awt.*;
import java.awt.event.*;
import java.io.IOException;
import java.io.InputStream;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.*;
import javax.swing.border.*;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
import java.util.regex.*;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.DocumentFilter;
import javax.swing.text.PlainDocument;

public class UserDataPanel extends JPanel {

    //Final Fields
    final String XMLCOUNTRIES = "/data/xml/countries.xml";
    final Color ERRORCOLOR = new Color(153, 31, 18);
    final int USERDATALENGTH = 20;
    final int EMAILLENGTH = 40;
    final String EMAILPATTERN = ".+@.+\\.[a-z]+";
    // Fields
    private JPanel pnlUserData;
    private JLabel welcomeTitle;
    private JPanel contentPanel;
    private JLabel textLabel;
    private JPanel titlePanel;
    private JTextField txtUsername;
    private JPasswordField pwfPassword;
    private JPasswordField pwfPasswordCheck;
    private JTextField txtFirstName;
    private JTextField txtLastName;
    private JComboBox cboCountry;
    private JTextField txtEmail;
    private JLabel lblErrors;

    public UserDataPanel() {

        super();

        contentPanel = getContentPanel();
        contentPanel.setBorder(new EmptyBorder(new Insets(10, 10, 10, 10)));

        titlePanel = new javax.swing.JPanel();
        textLabel = new javax.swing.JLabel();

        setLayout(new java.awt.BorderLayout());


        titlePanel.setLayout(new java.awt.BorderLayout());
        titlePanel.setBackground(Color.gray);

        textLabel.setBackground(Color.gray);
        textLabel.setFont(new Font("MS Sans Serif", Font.BOLD, 14));
        textLabel.setText("Personal Data");
        textLabel.setBorder(new EmptyBorder(new Insets(10, 10, 10, 10)));
        textLabel.setOpaque(true);

        titlePanel.add(textLabel, BorderLayout.CENTER);

        add(titlePanel, BorderLayout.NORTH);
        JPanel secondaryPanel = new JPanel();
        secondaryPanel.add(contentPanel, BorderLayout.NORTH);
        add(secondaryPanel, BorderLayout.WEST);

    }

    private JPanel getContentPanel() {

        JPanel contentPanel1 = new JPanel();

        welcomeTitle = new javax.swing.JLabel();
        pnlUserData = new javax.swing.JPanel();

        contentPanel1.setLayout(new java.awt.BorderLayout());

        welcomeTitle.setText("Please fill in your personal information:");
        contentPanel1.add(welcomeTitle, java.awt.BorderLayout.NORTH);


        pnlUserData.setLayout(new java.awt.GridLayout(0, 2, 0, 8));
        pnlUserData.setBorder(new EmptyBorder(new Insets(20, 20, 10, 10)));

        JLabel lblGebruikersnaam = new JLabel("Username: ");
        txtUsername = new JTextField();

        PlainDocument modelUsername = (PlainDocument) txtUsername.getDocument();

        modelUsername.setDocumentFilter(new MyDocumentFilter(USERDATALENGTH));

        txtUsername.addFocusListener(new FocusListener() {

            public void focusGained(FocusEvent e) {
                txtUsername.setBackground(Color.white);
                txtUsername.selectAll();
            }

            public void focusLost(FocusEvent e) {
                txtUsernameCheck();
            }
        });

        JLabel lblPassword = new JLabel("Password: ");
        pwfPassword = new JPasswordField();

        PlainDocument modelPassword = (PlainDocument) pwfPassword.getDocument();

        modelPassword.setDocumentFilter(new MyDocumentFilter(USERDATALENGTH));

        pwfPassword.addFocusListener(new FocusListener() {

            public void focusGained(FocusEvent e) {
                pwfPassword.setBackground(Color.white);
                pwfPassword.selectAll();
            }

            public void focusLost(FocusEvent e) {
                pwfPasswordCheck();
            }
        });

        JLabel lblWachtwoordCheck = new JLabel("Re-enter Password: ");
        setPwfPasswordCheck(new JPasswordField());
        PlainDocument modelPasswordAgain = (PlainDocument) getPwfPasswordCheck().getDocument();

        modelPasswordAgain.setDocumentFilter(new MyDocumentFilter(USERDATALENGTH));

        pwfPasswordCheck.addFocusListener(new FocusListener() {

            public void focusGained(FocusEvent e) {
                pwfPasswordCheck.setBackground(Color.white);
                pwfPasswordCheck.selectAll();
            }

            public void focusLost(FocusEvent e) {
                pwfPasswordAgainCheck();
            }
        });

        JLabel lblFirstName = new JLabel("First name: ");
        txtFirstName = new JTextField();

        PlainDocument modelFirstName = (PlainDocument) txtFirstName.getDocument();

        modelFirstName.setDocumentFilter(new MyDocumentFilter(USERDATALENGTH));

        txtFirstName.addFocusListener(new FocusListener() {

            public void focusGained(FocusEvent e) {
                txtFirstName.setBackground(Color.white);
                txtFirstName.selectAll();
            }

            public void focusLost(FocusEvent e) {
                txtFirstNameCheck();
            }
        });


        JLabel lblLastName = new JLabel("Last Name: ");
        txtLastName = new JTextField();

        PlainDocument modelLastName = (PlainDocument) txtLastName.getDocument();
        modelLastName.setDocumentFilter(new MyDocumentFilter(USERDATALENGTH));

        txtLastName.addFocusListener(new FocusListener() {

            public void focusGained(FocusEvent e) {
                txtLastName.setBackground(Color.white);
                txtLastName.selectAll();
            }

            public void focusLost(FocusEvent e) {
                txtLastNameCheck();
            }
        });

        JLabel lblCountry = new JLabel("Country: ");

        cboCountry = new JComboBox();
        fillCboCountries();

        JLabel lblEmail = new JLabel("E-mail:");
        txtEmail = new JTextField();

        PlainDocument modelEmail = (PlainDocument) txtEmail.getDocument();
        modelEmail.setDocumentFilter(new MyDocumentFilter(EMAILLENGTH));

        txtEmail.addFocusListener(new FocusListener() {

            public void focusGained(FocusEvent e) {
                txtEmail.setBackground(Color.white);
                txtEmail.selectAll();
            }

            public void focusLost(FocusEvent e) {
                txtEmailCheck();

            }
        });

        pnlUserData.add(lblGebruikersnaam);
        pnlUserData.add(getTxtUsername());
        pnlUserData.add(lblPassword);
        pnlUserData.add(getPwfPassword());
        pnlUserData.add(lblWachtwoordCheck);
        pnlUserData.add(getPwfPasswordCheck());
        pnlUserData.add(lblFirstName);
        pnlUserData.add(getTxtFirstName());
        pnlUserData.add(lblLastName);
        pnlUserData.add(getTxtName());
        pnlUserData.add(lblCountry);
        pnlUserData.add(getCboCountry());
        pnlUserData.add(lblEmail);
        pnlUserData.add(getTxtEmail());



        contentPanel1.add(pnlUserData, java.awt.BorderLayout.CENTER);

        setLblErrors(new JLabel("Please fill out the form correctly"));
        getLblErrors().setBorder(new EmptyBorder(0, 20, 0, 0));
        getLblErrors().setForeground(ERRORCOLOR);
        getLblErrors().setVisible(false);
        contentPanel1.add(getLblErrors(), BorderLayout.SOUTH);

        return contentPanel1;
    }

    private static class MyDocumentFilter extends DocumentFilter {

        private int size;

        public MyDocumentFilter(int size) {
            this.size = size;
        }

        @Override
        public void replace(FilterBypass fb, int offset, int length, String text, AttributeSet attrs) throws BadLocationException {
            if (fb.getDocument().getLength() + text.length() > size) {
                return;
            }

            super.replace(fb, offset, length, text, attrs);
        }
    }

    public void fillCboCountries() {

        try {

             InputStream input = getClass().getResourceAsStream(XMLCOUNTRIES);
             DocumentBuilder documentBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
             
             Document document = documentBuilder.parse(input);
             
            NodeList nlCountriesMain = document.getElementsByTagName("countries");
            Node nCountryMain = nlCountriesMain.item(0);
            NodeList nlCountries = nCountryMain.getChildNodes();
            for (int countCountries = 0; countCountries < nlCountries.getLength(); countCountries++) {
                Node nCountry = nlCountries.item(countCountries);

                if (nCountry.getNodeName().equals("country")) {
                    cboCountry.addItem(nCountry.getFirstChild().getNodeValue());
                }
            }

        }  catch (SAXException ex) {
            Logger.getLogger(MaiaWorld.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            Logger.getLogger(MaiaWorld.class.getName()).log(Level.SEVERE, null, ex);
        } catch (ParserConfigurationException ex) {
            Logger.getLogger(MaiaWorld.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    // <editor-fold defaultstate="collapsed" desc="Check user data">
    public boolean pwfPasswordCheck() {
        boolean result = false;

        char[] Password = pwfPassword.getPassword();
        StringBuffer stb = new StringBuffer();
        for (char c : Password) {
            stb.append(c);
        }
        String clearPass = stb.toString();

        if (clearPass.trim().equals("")) {
            pwfPassword.setBackground(ERRORCOLOR);
            lblErrors.setVisible(true);
            result = false;
        } else {
            pwfPassword.setBackground(Color.WHITE);
            lblErrors.setVisible(false);
            result = true;
        }
        return result;

    }

    public boolean pwfPasswordAgainCheck() {
        boolean result = false;

        char[] Password = pwfPasswordCheck.getPassword();
        StringBuffer stb = new StringBuffer();
        for (char c : Password) {
            stb.append(c);
        }
        String clearPass = stb.toString();

        if (clearPass.trim().equals("")) {
            pwfPasswordCheck.setBackground(ERRORCOLOR);
            lblErrors.setVisible(true);
            result = false;
        } else {
            pwfPasswordCheck.setBackground(Color.WHITE);
            lblErrors.setVisible(false);
            result = true;
        }
        return result;
    }

    public boolean pwfPasswordDoubleCheck() {
        boolean result = false;

        char[] Password1 = pwfPassword.getPassword();
        char[] Password2 = pwfPasswordCheck.getPassword();
        StringBuffer stb = new StringBuffer();
        StringBuffer stb2 = new StringBuffer();
        for (char c : Password1) {
            stb.append(c);
        }
        for (char c : Password2) {
            stb2.append(c);
        }

        String clearPass1 = stb.toString();
        String clearPass2 = stb2.toString();

        if (pwfPassword.getPassword().length == 0 || pwfPasswordCheck.getPassword().length == 0) {

            pwfPassword.setBackground(ERRORCOLOR);
            pwfPasswordCheck.setBackground(ERRORCOLOR);
            lblErrors.setVisible(true);
            result = false;

        } else {
            if (clearPass1.equals(clearPass2)) {
                pwfPassword.setBackground(Color.WHITE);
                pwfPasswordCheck.setBackground(Color.WHITE);
                lblErrors.setVisible(false);
                result = true;
            } else {
                pwfPassword.setBackground(ERRORCOLOR);
                pwfPasswordCheck.setBackground(ERRORCOLOR);
                lblErrors.setVisible(true);
                result = false;
            }

        }
        return result;
    }

    public boolean txtFirstNameCheck() {
        boolean result = false;
        if (txtFirstName.getText().trim().equals("")) {
            txtFirstName.setBackground(ERRORCOLOR);
            lblErrors.setVisible(true);
            result = false;
        } else {
            txtFirstName.setBackground(Color.WHITE);
            lblErrors.setVisible(false);
            result = true;
        }
        return result;

    }

    public boolean txtLastNameCheck() {
        boolean result = false;
        if (txtLastName.getText().trim().equals("")) {
            txtLastName.setBackground(ERRORCOLOR);
            lblErrors.setVisible(true);
            result = false;
        } else {
            txtLastName.setBackground(Color.WHITE);
            lblErrors.setVisible(false);
            result = true;
        }
        return result;
    }

    public boolean txtUsernameCheck() {
        boolean result = false;
        if (txtUsername.getText().trim().equals("")) {
            txtUsername.setBackground(ERRORCOLOR);
            lblErrors.setVisible(true);
            result = false;
        } else {
            txtUsername.setBackground(Color.WHITE);
            lblErrors.setVisible(false);
            result = true;
        }
        return result;
    }

    public boolean txtEmailCheck() {

        Pattern p = Pattern.compile(EMAILPATTERN);

        Matcher m = p.matcher(txtEmail.getText());

        //check whether match is found 
        boolean matchFound = m.matches();

        if (!matchFound) {
            txtEmail.setBackground(ERRORCOLOR);
            lblErrors.setVisible(true);

        } else {
            txtEmail.setBackground(Color.WHITE);
            lblErrors.setVisible(false);
        }

        return matchFound;

    }
    // </editor-fold>
    // <editor-fold defaultstate="collapsed" desc="Getters and setters">                      
    public JLabel getLblErrors() {
        return lblErrors;
    }

    public void setLblErrors(JLabel lblErrors) {
        this.lblErrors = lblErrors;
    }

    public JPasswordField getPwfPasswordCheck() {
        return pwfPasswordCheck;
    }

    public void setPwfPasswordCheck(JPasswordField pwfPasswordCheck) {
        this.pwfPasswordCheck = pwfPasswordCheck;
    }

    public JTextField getTxtFirstName() {
        return txtFirstName;
    }

    public JTextField getTxtName() {
        return txtLastName;
    }

    public JTextField getTxtUsername() {
        return txtUsername;
    }

    public JPasswordField getPwfPassword() {
        return pwfPassword;
    }

    public JComboBox getCboCountry() {
        return cboCountry;
    }

    public JTextField getTxtEmail() {
        return txtEmail;
    }
    // </editor-fold>    
}
